home *** CD-ROM | disk | FTP | other *** search
- {******************************************************************}
- { }
- { Mancala }
- { Turbo Pascal for Windows }
- { Copyright (c) 1991 by Swan Software. All rights reserved. }
- { }
- {******************************************************************}
-
- { uglobals.pas -- Global declarations for Mancala }
-
- unit Uglobals;
-
- interface
-
- uses WinTypes, WinProcs, Idents;
-
- const
-
- app_Name = 'Mancala'; { Application name and window title }
-
-
- {- Search procedure in usearch uses search level to know which
- side is moving. Even values represent human moves; odd values
- represent computer moves. The following constants are for calling
- procedures also called by search when a level variable is not
- available (makemove for example) }
-
- human = 0; { Even value = human move }
- computer = 1; { Odd value = computer move }
-
-
- {- The maxstack constant controls the total number of moves that
- can be maintained at one time. See also variables movestack and
- moveindex. Empirical tests indicate that 250 should be more than
- enough room to handle a search ply level of 7 (possibly 8). }
-
- maxStack = 250; { Maximum size of moverec stack }
-
-
- {- Maximum look-ahead. Should be odd so that computer searches its
- own moves on the deepest level. }
-
- maxSearchDepth = 7;
-
-
- {- Other variables, mostly self explanatory. }
-
- maxCups = 14; { 6 cups + 1 kalah per player }
- maxCupIndex = MAXCUPS - 1; { Used in FOR loops, etc. }
- defaultPebbles = 3; { Starting number of pebbles per cup }
- maxPebbles = 9; { Maximum pebbles per cup allowed }
-
-
- {- Context-sensitive help "context" identifiers }
-
- hc_menu_game = 100;
- hc_command_new = 105;
- hc_command_exit = 110;
- hc_menu_edit = 115;
- hc_command_options = 120;
- hc_command_level = 125;
- hc_menu_action = 130;
- hc_command_replay = 135;
- hc_command_pass = 140;
- hc_command_switch = 145;
- hc_menu_help = 150;
- hc_command_index = 155;
- hc_command_using_help = 160;
- hc_command_about = 165;
-
-
- type
-
-
- {- The CupIndex is the range of indexes allowed into the game
- board. This type is specific to Mancala only. Other games using the
- search engine do not need this. }
-
- CupIndex = 0 .. maxCupIndex;
-
-
- {- The game board in Mancala is a simple array of integers
- representing the number of pebbles in each cup. When designing a new
- game, you must create a Board data type, which can be any structure
- you want, a record, an array, or whatever you need. }
-
- Board = array[CupIndex] of Integer;
-
-
- {- Type OneMove defines the nature of a single move. In this
- game, a move is simply the cup index number. Another game could
- define OneMove as a string, or a coordinate on an 8x8 board, or a
- record containing a from position, a to position, and maybe flags to
- represent captures, and so on. In any case, you must define what
- OneMove is. }
-
- OneMove = CupIndex;
-
-
- {- Stack indexes locate positions in the MoveStack and BoardStack
- arrays. The indexes may be zero, in which case the arrays are
- empty. The stack range type defines the size of the MoveStack and
- BoardStack arrays. }
-
- StackIndex = 0 .. maxStack;
- StackRange = 1 .. maxStack;
-
-
- {- A MoveRec contains one move and a score value representing the
- board evaluation (from the computer's point of view). The BoardIndex
- indexes the BoardStack array, locating the Gameboard after making
- this move, plus other details such as the Win flag. }
-
- MoveRec = record
- Move: OneMove; { The move }
- Score: Integer; { The evaluation score }
- BoardIndex: StackRange; { The gameboard after moving }
- end;
-
-
- {- A ListRec contains an index to the first move of a list of
- moves for a certain Gameboard position, plus the count of moves on
- that list. These moves are stacked in the Movestack. This record is
- returned by MoveGen. A zero count indicates no legal moves for the
- player. In that case, field indexes are meaningless. }
-
- Listrec = record
- FirstIndex: StackRange; { First move on MoveStack }
- LastIndex: StackRange; { Last move on MoveStack }
- Count: Integer; { Number of moves on list }
- end;
-
-
- {- A BoardRec stores various game facts to make it easy to create
- multiple playing boards during move searches. }
-
- Boardrec = record
- GameBoard: Board; { The current position }
- GoAgain: Boolean; { True if player goes again }
- Win: Boolean; { True if either side wins }
- WinningSide: Integer { Valid if Win is true }
- end;
-
-
- var
-
- Side: Integer; { Side to move }
- SelfPlay: Boolean; { True for auto play }
- CurrentMessage: Integer; { Current message index }
- XMax, YMax: Integer; { Maximum display dimensions }
- XCenter, YCenter: Integer; { Display center coordinate }
- XBase, YBase: Integer; { Gameboard base coordinate }
- CBackground: TColorRef; { Color of window background }
- COuterCup: TColorRef; { Color of outer cup }
- CPen: TColorRef; { Color of pen (outlines) }
- CInnerShadow: TColorRef; { Color of inner shadow }
- HumanMove: Integer; { -1 = none; >= 0 = selected cup number }
-
-
- {- Indexes to computer's and human's kalah (home) and playing
- cups. The game is designed to use any number of cups, but the text
- interface is fixed to 6 cups per player. So, unless you change the
- interface, don't try to change the initial assignments to these
- variables. }
-
- CompKalah: CupIndex; { Index to computer's kalah }
- CompFirstCup: CupIndex; { Index to computer's first cup }
- CompLastCup: CupIndex; { Index to computer's last cup }
- HumanKalah: CupIndex; { Index to human's kalah }
- HumanFirstCup: CupIndex; { Index to human's first cup }
- HumanLastCup: CupIndex; { Index to human's last cup }
-
-
- {- The number of pebbles per cup may be set to any value, but large
- numbers will cause best-move searches to take a very long time. The
- PebblesDiv2 value equals the number of pebbles required to win. Ties
- are not possible. }
-
- PebblesPerCup: Integer; { Number of pebbles per cup }
- PebblesDiv2: Integer; { Number of pebbles needed to win }
-
-
- {- The BestMove is the result of calling Search. As long as you
- call search with at least one move for the current gameboard,
- BestMove will hold the computer's choice of moves for any search
- depth. }
-
- BestMove: OneMove;
-
-
- {- LowLevel is the starting search level. Search uses this
- variable to know when to assign the best move on a level to the
- global BestMove variable. }
-
- LowLevel: Integer;
-
-
- {- Set MaxPly to any value from 1 to maxSearchDepth before calling
- Search, which will examine that many levels plus one or two in the
- case of GoAhead moves (those where the player continues the turn).
- You may change MaxPly at any time during a game--it does not have to
- remain fixed for every move. Set MaxPly to an odd value to evaluate
- computer positions on the deepest level, or make it even to evaluate
- human responses on that level. }
-
- MaxPly: 1 .. maxSearchDepth;
-
-
- {- The MoveList stack contains lists of moves for a certain
- Gameboard position. Procedure MoveGen creates the move list, storing
- each move record on the stack. The MoveIndex points to the current
- top of the stack, which always contains a move record unless the
- stack is empty (MoveIndex=0). }
-
- MoveIndex: StackIndex;
- MoveStack: array[StackRange] of MoveRec;
-
-
- {- The BoardStack holds a copy of the Gameboard after making each
- move on the MoveList. Move records on the MoveStack contain the
- field BoardIndex, which locates a game board copy in this array.
- MoveIndex serves as the BoardStack stack pointer. }
-
- BoardStack: array[StackRange] of BoardRec;
-
-
- {- The MainPosition is the board on which all moves are made. }
-
- MainPosition: BoardRec;
-
-
- {- The cupcoords array stores the anchor coordinate for each displayed
- cup on the gameboard. All references to the cup, mouse clicks, pebble
- animations, etc., are made by passing an index referring to this array. }
-
- CupCoords: array[CupIndex] of TPoint;
-
-
- {- Instant-replay information }
-
- ReplayOk: Boolean;
- ReplayBoard: BoardRec;
- ReplayMove: OneMove;
- ReplaySide: Integer;
-
-
- {- Bitmap handle for flashing cup to show computer's move }
-
- FlashBits: HBitmap;
-
-
- implementation
-
-
- {- Perform various initializations for this unit }
-
- begin
- CurrentMessage := 1;
- CBackground := RGB(255, 255, 255);
- COuterCup := RGB(192, 31, 51);
- CPen := RGB(0, 0, 0);
- CInnerShadow := RGB(64, 64, 0);
- CompKalah := 0;
- HumanKalah := maxCups div 2;
- PebblesPerCup := DefaultPebbles;
- CompFirstCup := HumanKalah + 1;
- CompLastCup := MaxCupIndex;
- HumanFirstCup := 1;
- HumanLastCup := HumanKalah - 1;
- MaxPly := maxSearchDepth;
- XMax := 524;
- YMax := 360 + GetSystemMetrics(sm_CYMenu);
- XCenter := GetSystemMetrics(sm_CXScreen) div 2;
- YCenter := GetSystemMetrics(sm_CYScreen) div 2;
- XBase := (XMax - 472) div 2;
- YBase := (YMax div 2) - 64;
- HumanMove := -1;
- end.
-
-
- { ----------------------------------------------------------------
- Copyright (c) 1991 by Swan Software. All rights reserved.
- Revision 1.00 Date: 8/21/1991
- ---------------------------------------------------------------- }
-